package org.zxl.iotest.netty.protobuf.server;

import com.google.protobuf.TextFormat;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;
import org.zxl.iotest.netty.protobuf.proto.RegisterEntity;
import org.zxl.iotest.netty.protobuf.proto.StudentEntity;
import org.zxl.iotest.netty.protobuf.util.ClientMessageID;
import org.zxl.iotest.netty.protobuf.util.ZxlMsg;

import java.util.Objects;

/**
 * @author zhangxiaolong
 * @date 2025-02-16 09:29
 **/
@Slf4j
public class ProtobufInbondHandler extends ChannelInboundHandlerAdapter {
//    public ProtobufInbondHandlerAdapter() {
//        super();
//    }

//    @Override
//    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
//        log.info("channelRegistered");
//    }
//
//    @Override
//    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
//        log.info("channelUnregistered");
//    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        String channelID = ctx.channel().id().toString();
        log.info("channelActive,channelID:"+ channelID);

        ClientManage.ID_CHANNEL_MAP.put(channelID, new Client(channelID, ctx.channel()));
        ctx.fireChannelActive();
    }

//    @Override
//    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
//        log.info("channelInactive");
//    }

//    protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
//        return in.readableBytes() < this.frameLength ? null : in.readRetainedSlice(this.frameLength);
//    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
//        super.channelRead(ctx, msg);
        ByteBuf buf = (ByteBuf) msg;
        ZxlMsg zxlMsg = ServerMessageParse.parse(buf);

        /*byte[] msgIdBytes = new byte[4];
        buf.readBytes(msgIdBytes);
        int msgId = ByteUtils.bytesToIntBE(msgIdBytes);
        log.info("msgId:"+msgId);
        */

        String channelID = ctx.channel().id().toString();

        Client client = ClientManage.ID_CHANNEL_MAP.get(channelID);
        if(client == null){
            client = new Client(channelID, ctx.channel());
            ClientManage.ID_CHANNEL_MAP.put(channelID, client);
        }


        byte[] msgContentBytes = new byte[zxlMsg.getMsgLen()];
        buf.readBytes(msgContentBytes);

        if (Objects.equals(zxlMsg.getMsgId() , ClientMessageID.REGISTER)) {
            log.info("register");

//            byte[] msgLengthBytes = new byte[4];
//            buf.readBytes(msgLengthBytes);
//            int msgLength = ByteUtils.bytesToIntBE(msgLengthBytes);
//            log.info("msgLength:"+msgLength);

            RegisterEntity registerEntity = RegisterEntity.parseFrom(msgContentBytes);
            log.info("registerEntity:"+ TextFormat.printToString(registerEntity));

            long clientUuid = registerEntity.getServiceUuid();

//            CommonResult commonResult = CommonResult.parseFrom(msgContentBytes);
//            log.info("commonResult:"+ TextFormat.printToString(commonResult));
//
//            long clientUuid = commonResult.getIntCodeId();
            client.setClientUuid(clientUuid);

            log.info("register done, channelId:"+channelID+";clientUuid:"+clientUuid);
            return;
        }
        if (Objects.equals(zxlMsg.getMsgId() , ClientMessageID.HEARTBEAT)) {
            client.refreshHeartBeatTime();
            log.info("heartbeat done, channelId:"+channelID+";clientUuid:"+client.getClientUuid());
        }
        else {
            log.info("common");

//            byte[] msgLengthBytes = new byte[4];
//            buf.readBytes(msgLengthBytes);
//            int msgLength = ByteUtils.bytesToIntBE(msgLengthBytes);
//            log.info("msgLength:"+msgLength);

//            byte[] msgContentBytes = new byte[zxlMsg.getMsgLen()];
//            buf.readBytes(msgContentBytes);
//            CommonResult commonResult = CommonResult.parseFrom(msgContentBytes);
//
//            log.info("common done, channelId:"+channelID+";clientUuid:"+client.getClientUuid()+";commonResult:"+ TextFormat.printToString(commonResult));

            StudentEntity studentEntity = StudentEntity.parseFrom(msgContentBytes);
            log.info("studentEntity:"+ TextFormat.printToString(studentEntity));

            return;
        }

    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        log.info("channelReadComplete");
        ctx.flush();
        ctx.fireChannelReadComplete();
    }

//    @Override
//    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
//        log.info("userEventTriggered");
//
//
//    }

//    @Override
//    public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
//        log.info("channelWritabilityChanged");
//    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.info("exceptionCaught");
        cause.printStackTrace();
        ctx.close();
    }
}
